/**************************************************************************
 * @doc EMV
 * @module EMVTC |
 * Source code for the EMV TC Upload Resend
 *
 * <nl>Developer   :   Teo Kia Soon
 * <nl>Notes       :
 *
 * @head3 EMV Functions |
 * @index | EMV
 * @end
 *
 * Copyright (c) 1996-2005 by VeriFone Inc. All rights reserved.
 *
 * No part of this software may be used, stored, compiled, reproduced,
 * modified, transcribed, translated, transmitted, or transferred, in any form
 * or by any means whether electronic, mechanical, magnetic, optical,
 * or otherwise, without the express prior written permission of VeriFone, Inc.
 *
 * Revision History
 * ------------------------------------------------------------------------
 *  15 Jan 2006   TEO Kia Soon    Initially Creation
 *
 *
 ********************************************************************************/
#include <project.h>
#define EMV_C

#include <sizes.h>
#include <aclconio.h>
#include <stdio.h>
#include <stdlib.h>
#include <acldev.h>
#include <aclstr.h>
#include <aclutil.h>
#include <prot8583.h>
#include <define.h>
#include <transact.h>
#include <dbmgr.h>
#include <mdlfuncs.h>
#include <svc.h>
#include <protocol.h>
#include <packet.h>
#include <tran.h>
#include <comm.h>
#include <modem.h>
#include <ppt.h>
#include <piputl.h>
#include <pipmsg.h>
#include <isoutl.h>
#include <isoload.h>
#include <ifldtbl.h>
#include <msg.h>
#include <msgfuncs.h>
#include <bdt.h>
#include <hdt.h>
#include <trt.h>
#include <mht.h>
#include <iit.h>
#include <accum.h>
#include <form.h>
#include <date.h>
#include <mem.h>
#include <spdebug.h>
#include <funcids.h>
#include <pbatch.h>
#include <errno.h>
#include <ascii.h>
#include <amexhost.h>
#include <pct.h>
#include <formater.h>
#include <table.h>
#include <string.h>
#include <confio.h>
#include <aclfile.h>
#include <format.h>
#include <spamsg.h>
#include <oper.h>
#include <batmsg.h>
#include <ui.h>
#include <tct.h>
#include <multilng.h>
#include <logo.h>
#include <settlbat.h>
#include <msgclrk.h>
#include <msgshf.h>
#include <menufunc.h>
#include <mit.h>
#include <applidl.h>
#include <tblutil.h>
#include <menus.h>
#include <Validt.h>
#include <stats.h>
#include <cardmsg.h>
#include <card.h>
#include <msg.h>
#include <define.h>
#include <entry.h>
#include <pinpad.h>
#include <ctype.h>
#include <gds.h>
#include <power.h>
#include <tip.h>
#include <iso8583.h>
#include <beetle.h>
#include <xmodem.h>
#include <modemmsg.h>
//#include <scdefine.h>
#include <rcptsegs.h>
#include <operate.h>

#include <libvoy.h>
#include <cardslot.h>
#include <EMVCWrappers.h>
#include <common.h>
#include <EMVCStructs.h>

#include <vxemvap.h>
#include <emvlib.h>
#include <estfuncs.h>
#include <mvtfuncs.h>
#include <mvt.h>
#include <est.h>
#include <confproto.h>

#include "..\cpacsrc\cpacids.h"
#include "..\cpacsrc\cpacsize.h"
#include "..\cpacsrc\cpacmsg.h"
#include "..\cpacsrc\cpacsrc.h"

#include "..\EMVsrc\EMVmsg.h"
#include "..\EMVsrc\EMVsrc.h"
#include "..\EMVsrc\EMVcall.h"
#include "..\EMVsrc\EMVids.h"
#include "..\EMVsrc\EMVsrcdef.h"
#include "..\EMVsrc\EMViso.h"
#include "..\EMVsrc\EMVTC.h"

#include "..\citisrc\citisrc.h"
#include "..\imamsrc\imamsrc.h"

extern unsigned char szEMVField55[EMV_FIELD55_SIZE + 1];
extern unsigned char szEMVField23[EMV_FIELD23_SIZE + 1];
extern void vdOverLoadLoadDataFuncs(ISOLOAD srNewLoadDataFuncs[]);
extern int inCPACBaseRespValidation (VALIDATION_STRUCT *psrRespValStruct, int  inInternalVal);

char szTCFileName[FILENAME_SIZE + 1];
TC_REC srEMVTCRec;
TC_HEADER srEMVTCHeader;
ISOLOAD *srBackupLoadDataFuncs;
VS_BOOL fLastRecord=VS_FALSE;

ISOLOAD srEMVTCLoadDataFuncs[] = {
    2,vdLoadField02,
    3,vdLoadEMVTCField03,
    4,vdLoadCPACField04,
    11,vdLoadField11,
    12,vdLoadField12,
    13,vdLoadField13,
    14,vdLoadCPACField14,
    22,vdLoadEMVTCField22,
    23,vdLoadEMVTCField23,
    24,vdLoadCPACField24,
    25,vdLoadField25,
    35,vdLoadEMVTCField35,
    37,vdLoadEMVTCField37,
    38,vdLoadEMVTCField38,
    39,vdLoadEMVTCField39,
    41,vdLoadCPACField41,
    42,vdLoadCPACField42,
    44,vdDummy,
    45,vdLoadField45,
    48,vdLoadCITIField48,
    54,vdLoadCPACField54,
    55,vdLoadEMVTCField55,
    60,vdLoadEMVTCField60,
    61,vdLoadCPACField61,
    62,vdLoadCPACField62,
    63,vdLoadCPACField63
};



int inEMVStoreTCTrans(TRANSACTION_OBJECT *pobTran)
{
	int inTCRecNum=0;
	
	if(inEMVCreateTCRec(inGetHostHandle(), inGetMerchantNum())==VS_SUCCESS)
	{
		inTCRecNum=inEMVGetTCRec();
		if(inEMVSaveTCData(pobTran, inTCRecNum)==VS_SUCCESS)
		{
			inEMVIncreaseTCRec();
			return (VS_SUCCESS);
		}
		else
		        return (VS_ERR);
		    	
		
	}
	else
	        return VS_ERR;
}

int inEMVClearTCFilesByHost(TRANSACTION_OBJECT *pobTran)
{
    char szTCFileNameHost[FILENAME_SIZE + 1];
    sprintf(szTCFileNameHost, "%s%02d%02d",EMV_TC_FILENAME, inGetHostHandle(), inGetMerchantNum());
    strcat(szTCFileNameHost, TC_FILE_EXTN);
    if (inChkFileExist(szTCFileNameHost) == VS_SUCCESS)
	    remove(szTCFileNameHost);

    return VS_SUCCESS;	    
}

int inEMVClearTCFiles(TRANSACTION_OBJECT *pobTran)
{
    if (inChkFileExist(szTCFileName) == VS_SUCCESS)
	    remove(szTCFileName);

    return VS_SUCCESS;	    
}

void vdEMVSetTCFileName(int inHostNum, int inMerchNum)
{
	sprintf(szTCFileName, "%s%02d%02d",EMV_TC_FILENAME, inHostNum, inMerchNum);
	strcat(szTCFileName, TC_FILE_EXTN);
	return;
	
}
int inEMVCreateTCRec(int inHostHandle, int inMerchHandle)
{
	FHANDLE hHandle;

	
	vdEMVSetTCFileName(inHostHandle, inMerchHandle);
	if( inCheckFileExist(szTCFileName) != VS_SUCCESS)
	{
		hHandle = open(szTCFileName, O_RDWR|O_CREATE);
		if(hHandle<0)
		{
		    //LOG_PRINTF(("CREATED FILE FAILED"));
		    close(hHandle);
		    //return VS_ERROR;
		}
	}
	else
	{
		//LOG_PRINTF(("TC REC FOUND"))
		return VS_SUCCESS;
	}
	srEMVTCHeader.inTCPending=0;
	srEMVTCHeader.inRecNum=0;
	if(inEMVSaveTCHeader()!=VS_SUCCESS)
	{
		if(inEMVSaveTCHeader() !=VS_SUCCESS)
		{
		
		   return VS_ERR;
		}
	}
	memset(&srEMVTCRec,0x00,sizeof(TC_REC));
	inEMVSaveTCRec(0);
	return VS_SUCCESS;
} 

int inEMVIncreaseTCRec(void)
{
	if(inEMVLoadTCHeader()==VS_SUCCESS)
	{
		if(srEMVTCHeader.inTCPending==0)
		   srEMVTCHeader.inTCPending=1;
		   
		(srEMVTCHeader.inRecNum)++;
		
		return inEMVSaveTCHeader();
	}
	
	return VS_ERROR;
}

int inEMVCheckTCPending(void)
{
	if( inCheckFileExist(szTCFileName) != VS_SUCCESS)
		return 0;
	else
	{
	    if(inEMVLoadTCHeader()!=VS_SUCCESS)
	         return 0;
	    else
	         return  srEMVTCHeader.inTCPending;
	}
}

int inEMVGetTCRec(void)
{
	if( inCheckFileExist(szTCFileName) != VS_SUCCESS)
		return -1;
	else
	{
	    if(inEMVLoadTCHeader()!=VS_SUCCESS)
	         return -1;
	    else
	         return  srEMVTCHeader.inRecNum;
	}	
		
}


int inEMVLoadTCHeader (void)
{
	int inResult;
	FHANDLE hHandle;
	
	hHandle = open(szTCFileName, O_RDWR);
	if (hHandle < 0)
	{
		close(hHandle);
		return(VS_ERR);
	}	
	
	inResult = read(hHandle, (char *)&srEMVTCHeader, sizeof(TC_HEADER));
	
	if (inResult == 0L)          /* End of file reached, invalid index  */
	{
		close(hHandle);
		return(VS_ERR);
	}

	if (close(hHandle) < 0)
		return(VS_ERR);
	
	return(VS_SUCCESS);	
}

int inEMVSaveTCHeader (void)
{
	int inResult;
	FHANDLE hHandle;
	
	hHandle = open(szTCFileName, O_RDWR | O_CREAT);
	if (hHandle < 0)
	{
		close(hHandle);
		return(VS_ERR);
	}
		
	inResult = write(hHandle, (char *) &srEMVTCHeader, sizeof(TC_HEADER));
	if (inResult == 0L)          /* End of file reached, invalid index  */
	{
		close(hHandle);
		return(VS_ERR);
	}

	if (close(hHandle) < 0)
	{
		return(VS_ERR);
	}		

	return(VS_SUCCESS);
}

int inEMVClearTCHeader(void)
{
	memset(&srEMVTCHeader,0x00,sizeof(TC_HEADER));
	inEMVSaveTCHeader();
	return VS_SUCCESS;
}

int inEMVSaveTCRec (int inRecNum)
{
	int inResult;
	FHANDLE hHandle;
	long lnSeekResult, lnOffset;

	hHandle = open(szTCFileName, O_RDWR | O_CREAT);
	if (hHandle < 0)
	{
		LOG_PRINTF(("SAVE TC REC FAILED1"));
		close(hHandle);
		return(VS_ERR);
	}
		
	lnOffset = (long) (((long)sizeof(TC_HEADER)) + ((long) inRecNum * (long) sizeof(TC_REC)));
	lnSeekResult = lseek(hHandle, lnOffset, SEEK_SET);

	if (lnSeekResult != lnOffset)  /* Invalid index given, return VS_ERR */
	{
		LOG_PRINTF(("SAVE TC REC FAILED2"));
		close(hHandle);
		return(VS_ERR);
	}
	//LOG_PRINTFF((0x8L, "SAVE TC REC lnOffset=%d", lnOffset));	
	inResult = write(hHandle, (char *) &srEMVTCRec, sizeof(TC_REC));
	if (inResult == 0L)          /* End of file reached, invalid index  */
	{
		//LOG_PRINTF(("SAVE TC REC FAILED3"));
		close(hHandle);
		return(VS_ERR);
	}

	if (close(hHandle) < 0)
	{
		//LOG_PRINTF(("SAVE TC REC FAILED4"));
		return(VS_ERR);
	}		
	//LOG_PRINTFF((0x8L, "SAVE TC REC=%d", inRecNum));
	return(VS_SUCCESS);
}

int inEMVLoadTCRec (int inRecNum)
{
	int inResult;
	FHANDLE hHandle;
	long lnSeekResult, lnOffset;

	hHandle = open(szTCFileName, O_RDWR);
	if (hHandle < 0)
	{
		close(hHandle);
		return(VS_ERR);
	}	
	
	lnOffset = (long) (((long)sizeof(TC_HEADER)) + ((long) inRecNum * (long) sizeof(TC_REC)));
	lnSeekResult = lseek(hHandle, lnOffset, SEEK_SET);

	if (lnSeekResult != lnOffset)  /* Invalid index given, return VS_ERR */
	{
		close(hHandle);
		return(VS_ERR);
	}

	inResult = read(hHandle, (char *)&srEMVTCRec, sizeof(TC_REC));
		
	if (inResult == 0L)          /* End of file reached, invalid index  */
	{
		close(hHandle);
		return(VS_ERR);
	}

	if (close(hHandle) < 0)
		return(VS_ERR);
	
	return(VS_SUCCESS);
}

int inEMVClearTCRec(void)
{
	memset(&srEMVTCRec,0x00,sizeof(TC_REC));
	inEMVSaveTCRec(0);
	return VS_SUCCESS;
}
int inEMVSaveTCData(TRANSACTION_OBJECT *pobTran, int inRecNum)
{
#ifdef _TARG_68000
#else
	unsigned char bTagOutput[255];
#endif
	unsigned short usLength;
	char szMsgTypeId[MTI_SIZE + 1];
	srEMVTCRec.lnInvNum = pobTran->srBKey.lnInvNum;
	srEMVTCRec.lnTransactionAmount = pobTran->srBKey.lnTotalOfTransactionAmount;
	srEMVTCRec.lnStan = pobTran->srBRec.lnSTAN;
	vdGetCPACMsgTypeId(&pobTran->srBRec, (unsigned char *)szMsgTypeId);
	memcpy(srEMVTCRec.szMsgTypeId, szMsgTypeId, MTI_SIZE);
	memcpy(srEMVTCRec.szTCProcCode, srISO.pszField03, PROC_CODE_SIZE);
	memcpy(srEMVTCRec.szDate, pobTran->srBRec.szDate, EXP_DATE_SIZE);
	memcpy(srEMVTCRec.szExpDate, pobTran->srBRec.szExpDate, EXP_DATE_SIZE);
	memcpy(srEMVTCRec.szTime, pobTran->srBRec.szTime, DATE_SIZE);
	memcpy(srEMVTCRec.szPAN ,pobTran->srBRec.szPAN,PAN_SIZE);
	memcpy(srEMVTCRec.szPOSEntry ,srISO.pszField22,4);
	memcpy(srEMVTCRec.szPANSeq ,srISO.pszField23,4);
	memcpy(srEMVTCRec.stT2Data, pobTran->srBRec.stT2Data, TRACK2_SIZE);
	memcpy(srEMVTCRec.szRetRefNum, srISO.pszField37,RET_REF_SIZE);
	memcpy(srEMVTCRec.szAuthCode,srISO.pszField38,AUTH_CODE_SIZE);
	memcpy(srEMVTCRec.szRespCode,srISO.pszField39,RESP_CODE_SIZE);
	memset(srEMVTCRec.szTCField55, 0x00, sizeof(srEMVTCRec.szTCField55));
	inStoreTCEMVdata(pobTran, (unsigned char *)srEMVTCRec.szTCField55, &usLength);
	srEMVTCRec.inSizeField55 = (int)usLength;
	//LOG_PRINTFF((0x8L, "inEMVSaveTCData=%d", (srEMVTCRec.inSizeField55)));
	return inEMVSaveTCRec(inRecNum);
	
}

void vdEMVLoadTCData(TRANSACTION_OBJECT *pobTran, int inRecNum)
{

	inEMVLoadTCRec(inRecNum);
	pobTran->srBKey.lnInvNum = srEMVTCRec.lnInvNum;
	pobTran->srBKey.lnTotalOfTransactionAmount = srEMVTCRec.lnTransactionAmount;
	memcpy(pobTran->srBRec.szTime, srEMVTCRec.szTime, DATE_SIZE);
	memcpy(pobTran->srBRec.szDate, srEMVTCRec.szDate, EXP_DATE_SIZE);
	memcpy(pobTran->srBRec.szExpDate, srEMVTCRec.szExpDate, EXP_DATE_SIZE);
	memcpy(pobTran->srBRec.szPAN,srEMVTCRec.szPAN,PAN_SIZE);
	//LOG_PRINTFF((0x8L, "vdEMVLoadTCData=%d", (srEMVTCRec.inSizeField55)));
	//memcpy(srISO.pszField37,srEMVTCRec.szRetRefNum, RET_REF_SIZE);
	//memcpy(srISO.pszField38,srEMVTCRec.szAuthCode,AUTH_CODE_SIZE);
	//memcpy(srISO.pszField39,srEMVTCRec.szRespCode,RESP_CODE_SIZE);
	//inField55Len = srSCIBTCRec.inSizeField55;
	//memcpy(szField55,srSCIBTCRec.szTCField55,inField55Len+2);
}

VS_BOOL fCheckLastTCRec(int inRecNum)
{
	int inPendingNum=inEMVGetTCRec();
	if(inRecNum==(inPendingNum-1))
	{
	    fLastRecord=VS_TRUE;
	    return VS_TRUE;
	}	
	else
	{
	    fLastRecord=VS_FALSE;
	    return VS_FALSE;
	}
}

int inEMVSendTCAdvice(TRANSACTION_OBJECT *pobTran, PACKET_OBJECT* pobPacket)
{
	TRANSACTION_OBJECT obTran;
	long lnSTAN;
	vdEMVSetTCFileName(inGetHostHandle(), inGetMerchantNum());
	memcpy((char *)&obTran, (char *)pobTran,sizeof(TRANSACTION_OBJECT)); 
	
	if(inEMVCheckTCPending() > 0)
	{	
		int inPendingNum=inEMVGetTCRec();
		int i=0;
		LOG_PRINTFF((0x8L, "TC PENDING NUMBER=%d", inPendingNum));
		while(i<inPendingNum)
		{
			fCheckLastTCRec(i);
			vdEMVLoadTCData(pobTran, i);
			if( inEMVResendTCUpload( pobTran , pobPacket )!= VS_SUCCESS)
			{
				vdDisplayMessage("TC UpLoad Error !", WARNING_MSG);
				memcpy((char *)pobTran, (char *)&obTran,sizeof(TRANSACTION_OBJECT));
				inTCIncSTAN(); 
				return VS_ERR;
			}
			
			inTCIncSTAN();
			i++;
		}
		memcpy((char *)pobTran, (char *)&obTran,sizeof(TRANSACTION_OBJECT)); 
		
		lnSTAN = lnGetSTAN();
        	pobTran->srBRec.lnSTAN = lnSTAN;
        	pobTran->srBKey.lnOrgSTAN = pobTran->srBRec.lnSTAN;		
	}
	LOG_PRINTF(("END OF INEMVSETTLESENDTC"));
	inEMVClearTCFiles(pobTran);
	
	return VS_SUCCESS;
}

int inEMVCreateVariantStruct60(void) 
{
    short i;

    variant_struct* tmp;

    if ((tmp = (variant_struct *) pchAlloc(CPAC_TABLE60_SIZE * sizeof(variant_struct))) == NULL_CH) {
        return (VS_ERR);
    }

    psrVariant60 = tmp;
/*
	 variant_struct srBaseVariant60 [] =
        {
		{ 92,    500,  6, AV3_STR, (void *)srISO.pszField60), sizeof(srISO.pszField60)},
            	{ 96,    500,  6, AV3_STR, (void*)(srISO.pszField60), sizeof(srISO.pszField60) },
              { 97,    500,  6, AV3_STR, (void*)(srISO.pszField60), sizeof(srISO.pszField60) },
              { 00,    320, 22, AV3_STR, (void*)(srISO.pszField60), sizeof(srISO.pszField60) },
              { 02,    320, 22, AV3_STR, (void*)(srISO.pszField60), sizeof(srISO.pszField60) },
              { 20,    320, 22, AV3_STR, (void*)(srISO.pszField60), sizeof(srISO.pszField60)},
              { 22,    320, 22, AV3_STR, (void*)(srISO.pszField60), sizeof(srISO.pszField60) },
              { 09,    320, 22, AV3_STR, (void*)(srISO.pszField60), sizeof(srISO.pszField60) },
              { 29,    320, 22, AV3_STR, (void*)(srISO.pszField60), sizeof(srISO.pszField60)},
		{ 00,    420, 22, AV3_STR, (void*)(srISO.pszField60), sizeof(srISO.pszField60)},
		{ 02,    420, 22, AV3_STR, (void*)(srISO.pszField60), sizeof(srISO.pszField60) },
		{ 22,    420, 22, AV3_STR, (void*)(srISO.pszField60), sizeof(srISO.pszField60) },
		{ 02,    220, 12, AV3_STR, (void*)(srISO.pszField60), sizeof(srISO.pszField60)},
            }; */
    for (i = 0; i < CPAC_TABLE60_SIZE; i++) {
        tmp->convert_idx = AV3_STR;
        if (i < 16) {
            tmp->reference = (void *) srISO.pszField60;
            tmp->var_sz = sizeof(srISO.pszField60);
        }
        if (i < 3) {
            tmp->variant2 = 500;
            tmp->packet_sz = 6;
        } else
            tmp->packet_sz = 22;

        switch (i) {
        case 0:
            tmp->variant1 = 92;
            break;
        case 1:
            tmp->variant1 = 96;
            break;
        case 2:
            tmp->variant1 = 97;
            break;
        case 3:
            tmp->variant1 = 00;
            tmp->variant2 = 320;
            break;
        case 4:
            tmp->variant1 = 9;
            tmp->variant2 = 320;
            break;
        case 5:
            tmp->variant1 = 20;
            tmp->variant2 = 320;
            break;
        case 6:
            tmp->variant1 = 22;
            tmp->variant2 = 320;
            break;
        case 7:
            tmp->variant1 = 9;
            tmp->variant2 = 320;
            break;
        case 8:
            tmp->variant1 = 29;
            tmp->variant2 = 320;
            break;
        case 9:
            tmp->variant1 = 0;
            tmp->variant2 = 420;
            break;
        case 10:
            tmp->variant1 = 2;
            tmp->variant2 = 420;
            break;
        case 11:
            tmp->variant1 = 22;
            tmp->variant2 = 420;
            break;
        case 12:
            tmp->variant1 = 2;
            tmp->variant2 = 220;
            tmp->packet_sz = 12;
            break;
        case 13:
            tmp->variant1 = 22;
            tmp->variant2 = 220;
            tmp->packet_sz = 12;
            break;
        case 14:
            tmp->variant1 = 94;
            tmp->variant2 = 320;
            tmp->packet_sz = 12;
            break;
        case 15:
            tmp->variant1 = 2 ;
            tmp->variant2 = 200;
            tmp->packet_sz = 12;
            break;
        case 16:
            tmp->variant1 = 2 ;
            tmp->variant2 = 210;
            tmp->packet_sz = 12; 
        
         case 17:
            tmp->variant1 = 22;
            tmp->variant2 = 200;
            tmp->packet_sz = 12;
            break;
        case 18:
            tmp->variant1 = 22;
            tmp->variant2 = 210;
            tmp->packet_sz = 12; 
        case 19:
            tmp->variant1 = 94;
            tmp->variant2 = 220;
            tmp->packet_sz = 12;        
        case 20:
            tmp->variant1 = 0 + STOP;
            tmp->variant2 = 220;
            tmp->packet_sz = 12;
            break;
             
        }
        tmp++;
    }

    srBaseIsoFDT[FIELD60_POSITION].reference = (void *) psrVariant60;

    /*
        variant_struct srBaseVariant60 [] =
        {
        0  { 92,    500,  6, AV3_STR, VARIABLE(srISO.pszField60) },
            1  { 96,    500,  6, AV3_STR, VARIABLE(srISO.pszField60) },
            2  { 97,    500,  6, AV3_STR, VARIABLE(srISO.pszField60) },
            3  { 00,    320, 22, AV3_STR, VARIABLE(srISO.pszField60) },
            4  { 02,    320, 22, AV3_STR, VARIABLE(srISO.pszField60) },
            5  { 20,    320, 22, AV3_STR, VARIABLE(srISO.pszField60) },
            6  { 22,    320, 22, AV3_STR, VARIABLE(srISO.pszField60) },
            7  { 09,    320, 22, AV3_STR, VARIABLE(srISO.pszField60) },
            8  { 29,    320, 22, AV3_STR, VARIABLE(srISO.pszField60) },
            };
        */
    return(VS_SUCCESS);
}


int inEMVCreateVariantStruct63(void) 
{
    short i;
    variant_struct* tmp;

    if ((tmp = (variant_struct *) pchAlloc(CPAC_TABLE63_SIZE * sizeof(variant_struct))) == NULL_CH) {
        return (VS_ERR);
    }

    psrVariant63 = tmp;

    for (i = 0; i < CPAC_TABLE63_SIZE; i++) {
	
        tmp->convert_idx = AV3_STR;
        tmp->reference = (void *) srISO.pszField63;
        tmp->var_sz = sizeof(srISO.pszField63);
        if (i < 5) {
            tmp->variant2 = 500;
            tmp->packet_sz = 90;
        } else if (i != 8) {
            tmp->variant2 = 510;
            tmp->packet_sz = 90; /* 40-> 90 CPAC_UNBKL */
        } else {
            tmp->variant2 = 510;
            tmp->packet_sz = 90; /* 40-> 90 CPAC_UNBKL */
        }

        switch (i) {
        case 0:
            tmp->variant1 = 92;
            break;
        case 1:
            tmp->variant1 = 93;
            break;
        case 2:
            tmp->variant1 = 94;
            break;
        case 3:
            tmp->variant1 = 96;
            break;
        case 4:
            tmp->variant1 = 97;
            break;
        case 5:
            tmp->variant1 = 96;
            break;
        case 6:
	    tmp->variant1 = 93;
            break;
        case 7:
            tmp->variant1 = 94;
            break;
        case 8:
            tmp->variant1 = 92 + STOP;
            break;
        }
        tmp++;
    }
    srBaseIsoFDT[FIELD63_POSITION].packet_sz = 0;
    srBaseIsoFDT[FIELD63_POSITION].var_sz = 0;
    srBaseIsoFDT[FIELD63_POSITION].convert_idx = VARIANT;
    srBaseIsoFDT[FIELD63_POSITION].reference = (void *) psrVariant63;

    /*  psrVariant63[] =
    {
    { 92,   500,    90,      AV3_STR,    VARIABLE(srISO.pszField63) },
    { 93,   500,    90,      AV3_STR,    VARIABLE(srISO.pszField63) },
    { 94,   500,    90,      AV3_STR,    VARIABLE(srISO.pszField63) },
    { 96,   500,    90,      AV3_STR,    VARIABLE(srISO.pszField63) },
    { 97,   500,    90,      AV3_STR,    VARIABLE(srISO.pszField63) },
    { 96,   510,    40,      AV3_STR,    VARIABLE(srISO.pszField63) },
    { 93,   510,    40,      AV3_STR,    VARIABLE(srISO.pszField63) },
    { 94,   510,    40,      AV3_STR,    VARIABLE(srISO.pszField63) },
    { 92,   510,    40,      AV3_STR,    VARIABLE(srISO.pszField63) },
    };
    */
    return(VS_SUCCESS);
}

int inEMVResendTCUpload(TRANSACTION_OBJECT *pobTran , PACKET_OBJECT *pobPacket)
{
#ifdef _TARG_68000
#else
	char szLog[60+1];
	long lnBatchUploadSTAN;
#endif
	int inRetVal;
	short shTransCode, shPIPTransCode;

	
	pobPacket->inError = 0;			
	pobTran->inTransactionCode = TC_UPLOAD;
	pobTran->srBRec.inCode= TC_UPLOAD;
	pobTran->srTRTRec.TransactionCode = TC_UPLOAD;
	pobTran->srBRec.fCustNum = VS_TRUE;
	vdSetReversal(pobTran, VS_FALSE);
	pobTran->srBRec.lnSTAN = lnGetSTAN();	
	
	if (inEMVCreateVariantStruct60 () == VS_ERR)
    	{
		vdFree((char *)psrVariant60);
		vdSGErrorMessage(NO_MEM_ERR_MSG);
		return(VS_ERR);
    	}

	if (inEMVCreateVariantStruct63 () == VS_ERR)
	{
		vdFreeVariantTables();
		vdSGErrorMessage(NO_MEM_ERR_MSG);
		return(VS_ERR);
	}
	
	if( (psrHostData = psrCreateHostData()) == (HOST_8583_DATA *)NULL_CH )
	{
		vdFreeHostData(psrHostData);
		vdFreeVariantTables();
		vdSGErrorMessage(NO_MEM_ERR_MSG);
		return(VS_ERR);
	}
		
	if( (psrHostData->c8583_data = psrCreateCommData(pobTran, CPAC_SEND_SIZE, VS_TRUE)) == (COMM_8583_DATA *)NULL_CH )
	{
		vdSGErrorMessage(NO_MEM_ERR_MSG);
		vdFreeISO8583Data(psrHostData);
		return(VS_ERR);
	}
	
	psrHostData->c8583_data->transceiver = inImamTxRx8583;  //
#ifdef MODEM
	if (inGetUCLCommLink()==0) {  // to get resp timeout
		MODEM_OBJECT *obModem;
		obModem = (MODEM_OBJECT *)obCommunication.Data;
		psrHostData->c8583_data->comm_timeout         = obModem->shGetRespTimeOut(obModem->srCPT);  // for Response TimeOut
		psrHostData->c8583_data->wait_for_carrier     = obModem->shGetCarrierTimeOut(obModem->srCPT); // for Carier TimeOut
	}
#endif

	((VALIDATION_STRUCT *)(psrHostData->c8583_data->v_parms))->comm_struct = psrHostData->c8583_data;
																				/* Added for Custom base resp validation CPAC_VALID */
	psrHostData->c8583_data->validation  = (PFI_PVOID_INT)inCPACBaseRespValidation;
	psrHostData->c8583_data->comm_timeout         = 45; 
    	psrHostData->c8583_data->wait_for_carrier     = 45;
	psrHostData->reverse_flag = 0;
	psrHostData->c8583_data->transceiver = inTxRx8583;																/* Added for Custom base resp validation CPAC_VALID */
	vdGetReversalFileName((char *)stRevFileName, inGetHostHandle());
	
	srBackupLoadDataFuncs = psrLoadDataFuncs; //store original ISOLOAD data
	vdOverLoadLoadDataFuncs(srEMVTCLoadDataFuncs);

	shTransCode = shVerifyCPACTransType(pobTran);		
	
	inStoreTranFlexiData(pobTran, AMEX_PIP_TRANS_CODE, (unsigned char *)&shTransCode, 2);
	
	if ((shPIPTransCode = shLoadPIPTransCode(shTransCode)) == VS_ERR)
	{
		vdFreeISO8583Data(psrHostData);
		return (VS_ERR);
	}
	
	if(inGGCode()==REFUND&&fGetOffline(pobTran)&&(!pobTran->srBKey.fVoided))
		shPIPTransCode=A_REFUND_OFFLINE;
		
	errno=0;
	
	inRetVal = pip_trans((int)shPIPTransCode, psrHostData);
	
	vdFreeISO8583Data(psrHostData);
	vdFreeVariantTables();
	vdOverLoadLoadDataFuncs(srBackupLoadDataFuncs); // stored back the ISOLOAD table;

	if (inRetVal != PIP_APPROVAL) 
	{
		return VS_ERROR;	
   		//return(pobPacket->inError);
	}
	
	//vdFreeVariantTables();
	//vdFreeISO8583Data(psrHostData);
	
	return VS_SUCCESS;	
}

void vdLoadEMVTCField60(TRANSACTION_OBJECT* pobTran) {
    short inTranCode;
    long lnBatchUploadSTAN;

#ifdef ICICI
	#ifndef CITI_IND
    		long lnTotTransAmt;
	#endif /*CITI_IND*/
#endif /* ICICI  */

    char szMsgTypeId[MTI_SIZE + 1];
    unsigned char pszField37[FIELD37_SIZE + 1];  /* CPAC_UNBKL added */


   
	#ifdef ICICI
	#ifndef CITI_IND
		if ( (pobTran->srTRTRec.TransactionCode == VOID) || (pobTran->srTRTRec.TransactionCode == VOID_REFUND_OFFLINE) || (pobTran->srTRTRec.TransactionCode == VOID_REFUND)) //citi_ind added 2nd condition
    		{
        		if (pobTran->srBKey.fUploaded == VS_TRUE)
			{
            			if (inGetTipProcessing())
				{
					lnTotTransAmt = pobTran->srBRec.lnBaseTransactionAmount + pobTran->srBRec.lnTipAmount;
                			sprintf((char *) srISO.pszField60, SUBSTITUTE_LD, lnTotTransAmt);
				}
				else
					sprintf((char *)srISO.pszField60, SUBSTITUTE_LD, pobTran->srBRec.lnBaseTransactionAmount);
			}
			else
			{
				sprintf((char *)srISO.pszField60, SUBSTITUTE_LD, pobTran->srBRec.lnBaseTransactionAmount);
			}

        		pad((char *) srISO.pszField60, (char *) srISO.pszField60, '0', ISO_AMT_SIZE, RIGHT);                                //citi_ind added line
		}
		if (pobTran->srTRTRec.TransactionCode == VOID_SALE_OFFLINE ) //citi_ind added 2nd condition
		{																																												//void refund ->void refund offline
			if (pobTran->srBKey.fUploaded == VS_TRUE)
			{
				if (inGetTipProcessing())
				{
				
					lnTotTransAmt = pobTran->srBRec.lnBaseTransactionAmount + pobTran->srBRec.lnTipAmount;
					sprintf((char *)srISO.pszField60, SUBSTITUTE_LD, lnTotTransAmt);
				}
				else
					sprintf((char *)srISO.pszField60, SUBSTITUTE_LD, pobTran->srBRec.lnOldTotalTransactionAmount);
			}
			else
			{
				sprintf((char *)srISO.pszField60, SUBSTITUTE_LD, pobTran->srBRec.lnBaseTransactionAmount);
			}

			pad ((char *)srISO.pszField60, (char *)srISO.pszField60, '0',ISO_AMT_SIZE, RIGHT);								//citi_ind added line
		}
	#endif /*CITI_IND*/

	#ifdef CITI_IND
    	if (pobTran->srTRTRec.TransactionCode == VOID_SALE_OFFLINE)
	{
		if (pobTran->srBKey.fUploaded == VS_TRUE)
		{
			sprintf((char *)srISO.pszField60, SUBSTITUTE_LD, pobTran->srBRec.lnBaseTransactionAmount + pobTran->srBRec.lnTipAmount);
		}
		else
		{
            		sprintf((char *) srISO.pszField60, SUBSTITUTE_LD, pobTran->srBRec.lnOrigTotalTransactionAmount);
		}
        	pad((char *) srISO.pszField60, (char *) srISO.pszField60, '0', ISO_AMT_SIZE, RIGHT);
    	}

    	if ((pobTran->srTRTRec.TransactionCode == VOID) && (pobTran->srTRTRec.Offline == VS_TRUE))
	{
		if (pobTran->srBKey.fUploaded == VS_TRUE)
		{
			sprintf((char *)srISO.pszField60, SUBSTITUTE_LD, pobTran->srBRec.lnBaseTransactionAmount  + pobTran->srBRec.lnTipAmount);
		}
        	else
            		sprintf((char *) srISO.pszField60, SUBSTITUTE_LD, pobTran->srBRec.lnOrigTotalTransactionAmount);

		pad((char *) srISO.pszField60, (char *) srISO.pszField60, '0', ISO_AMT_SIZE, RIGHT);
    	}
	#endif /*NOT CITI_IND*/
#else

	#ifdef CITI_IND
	if ((pobTran->srTRTRec.TransactionCode == VOID_SALE_OFFLINE) || (pobTran->srTRTRec.TransactionCode == VOID) || (pobTran->srTRTRec.TransactionCode == VOID_REFUND_OFFLINE) || (pobTran->srTRTRec.TransactionCode == VOID_REFUND)) //citi_ind added 2nd condition
	{																																												//void refund ->void refund offline
		if (pobTran->srBKey.fUploaded == VS_TRUE){
			if (inGetTipProcessing()) {
					lnTotTransAmt = pobTran->srBRec.lnBaseTransactionAmount + pobTran->srBRec.lnTipAmount;
					sprintf((char *)srISO.pszField60, SUBSTITUTE_LD, lnTotTransAmt);
			}
			else sprintf((char *)srISO.pszField60, SUBSTITUTE_LD, pobTran->srBRec.lnBaseTransactionAmount);
		}
		else {
			sprintf((char *)srISO.pszField60, SUBSTITUTE_LD, pobTran->srBRec.lnOrigTotalTransactionAmount);
		}

		pad ((char *)srISO.pszField60, (char *)srISO.pszField60, '0',ISO_AMT_SIZE, RIGHT);
		map_reset(stOptionalMap, 48);								//citi_ind added line
	}
#endif /*CITI_IND*/

#ifndef CITI_IND
	if (pobTran->srTRTRec.TransactionCode == VOID_SALE_OFFLINE)
	{
		if (pobTran->srBKey.fUploaded == VS_TRUE){
			sprintf((char *)srISO.pszField60, SUBSTITUTE_LD, pobTran->srBRec.lnBaseTransactionAmount);
		}
		else {
			sprintf((char *)srISO.pszField60, SUBSTITUTE_LD, pobTran->srBRec.lnOrigTotalTransactionAmount);
		}
        pad ((char *)srISO.pszField60, (char *)srISO.pszField60, '0',ISO_AMT_SIZE, RIGHT);
	}


	if ((pobTran->srTRTRec.TransactionCode == VOID) && (pobTran->srTRTRec.Offline == VS_TRUE))
	{
		if (pobTran->srBKey.fUploaded == VS_TRUE)
		{
			sprintf((char *)srISO.pszField60, SUBSTITUTE_LD, pobTran->srBRec.lnBaseTransactionAmount);
		}
		else
		{
			sprintf((char *)srISO.pszField60, SUBSTITUTE_LD, pobTran->srBRec.lnOrigTotalTransactionAmount);
		}
        pad ((char *)srISO.pszField60, (char *)srISO.pszField60, '0',ISO_AMT_SIZE, RIGHT);
	}
#endif /*NOT CITI_IND*/

#endif   /*  ICICI   */
    if (pobTran->srTRTRec.TransactionCode == ADJUST || pobTran->srTRTRec.TransactionCode == CPAC_PHIL_ADJUST ||  /* 1.4_citiphil_don_DSC */
        pobTran->srTRTRec.TransactionCode == SALE_ADJST || pobTran->srTRTRec.TransactionCode == ADD_TIP_OFFLINE || pobTran->srTRTRec.TransactionCode == RET_ADJST || pobTran->srTRTRec.TransactionCode == TIP_ADJUST || pobTran->srTRTRec.TransactionCode == ADJUST_REFUND_OFFLINE || pobTran->srTRTRec.TransactionCode == ADJUST_PHONE_OFFLINE) {
        if (pobTran->srBKey.fUploaded == VS_TRUE)
            sprintf((char *) srISO.pszField60, SUBSTITUTE_LD, pobTran->srBRec.lnBaseTransactionAmount);
        else
            sprintf((char *) srISO.pszField60, SUBSTITUTE_LD, pobTran->srBRec.lnOrigTotalTransactionAmount);
        /*CPAC_UNBKL removed to add the following line
        */
        /*      sprintf((char *)srISO.pszField60, SUBSTITUTE_LD, pobTran->srBRec.lnBaseTransactionAmount);*/
        pad((char *) srISO.pszField60, (char *) srISO.pszField60, '0', ISO_AMT_SIZE, RIGHT);
    }



    inTranCode = pobTran->srBRec.inCode;

    switch (inTranCode) {
    case CLS_BATCH    :
    case CLS_BATCH_UPLOAD :
        long2str((char *) srISO.pszField60, lnGetBatchNum());
        /*
                    pad((char *)srISO.pszField60, (char *)srISO.pszField60, '0', inGetBatchNumSize(), RIGHT);
                    CPAC_UNBKL  removed to add the following line:: inGetBatchNumSize() => 6
        */
        pad((char *) srISO.pszField60, (char *) srISO.pszField60, '0', 6, RIGHT);

        break;
    case TC_UPLOAD  		:
    	 memcpy(szMsgTypeId, srEMVTCRec.szMsgTypeId, MTI_SIZE);
    	 sprintf((char *) srISO.pszField60, "%02x%02x%06ld", szMsgTypeId[0], szMsgTypeId[1], srEMVTCRec.lnStan);
	 pad((char *)srISO.pszField60, (char *)srISO.pszField60, ' ', 10, LEFT);
	 break;	 
    case BATCH_UPLOAD           :
        /* Load the Original Data Message in field 60 */
        /* Field 60 contains 4 digits of MID, 6 digits of STAN
           and 12 digits of Reserved space set to spaces.
           */
        vdGetCPACMsgTypeId(&pobTran->srBRec, (unsigned char *) szMsgTypeId);
        vdGetCPACRetRefNum(&pobTran->srBRec, pszField37);  /* CPAC_UNBKL added */

        lnBatchUploadSTAN = lnGetCPACBatchUploadSTAN(&pobTran->srBRec);
    	 sprintf((char *) srISO.pszField60, "%02x%02x%06ld", szMsgTypeId[0], szMsgTypeId[1], lnBatchUploadSTAN);
			pad((char *)srISO.pszField60, (char *)srISO.pszField60, ' ', 10, LEFT);
        break;
    default :
        return;
    }
}



void vdLoadEMVTCField39(TRANSACTION_OBJECT* pobTran) {
    int inTranCode;
    inTranCode = pobTran->srBRec.inCode;
    
    LOG_PRINTF(("vdLoadEMVTCField39"));
    if(inTranCode != TC_UPLOAD)
    {
    	memcpy((char *) srISO.pszField39, pobTran->srBRec.szRespCode, 2); 
    	srISO.pszField39[2] = 0x00;
    }  
    else
    {
    	memcpy(srISO.pszField39,srEMVTCRec.szRespCode,RESP_CODE_SIZE);
    	srISO.pszField39[RESP_CODE_SIZE-1] = 0x00;// imam 
    }	

    
}       

void vdLoadEMVTCField38(TRANSACTION_OBJECT* pobTran) {
    int inTranCode;

    inTranCode = pobTran->srBRec.inCode;
    LOG_PRINTF(("vdLoadEMVTCField38"));
    //   if (inTranCode == REFUND_OFFLINE)
    if (inTranCode == REFUND && fGetOffline(pobTran)) {
        MEMCLR(pobTran->srBRec.szAuthCode, AUTH_CODE_SIZE);
        memset(pobTran->srBRec.szAuthCode, '0', AUTH_CODE_SIZE);
        memset((char *) srISO.pszField38, '0', AUTH_CODE_SIZE);
    } else if(inTranCode != TC_UPLOAD){
        strlcpy((char *) srISO.pszField38, pobTran->srBRec.szAuthCode, AUTH_CODE_SIZE);
        pad((char *) srISO.pszField38, (char *) srISO.pszField38, SPACE, AUTH_CODE_SIZE, LEFT);
    }
    else if(inTranCode == TC_UPLOAD)
    {
    	 memcpy(srISO.pszField38,srEMVTCRec.szAuthCode,AUTH_CODE_SIZE);
    }
}

void vdLoadEMVTCField37(TRANSACTION_OBJECT* pobTran) {
    int inTranCode;
    inTranCode = pobTran->srBRec.inCode;
    LOG_PRINTF(("vdLoadEMVTCField37"));
    if(inTranCode != TC_UPLOAD)
    	vdGetCPACRetRefNum(&pobTran->srBRec, srISO.pszField37);
    else
    	memcpy(srISO.pszField37,srEMVTCRec.szRetRefNum, RET_REF_SIZE);
}

void vdLoadEMVTCField55(TRANSACTION_OBJECT* pobTran){
	//SVC_HEX_2_DSP((char *)srEMVTCRec.szTCField55, (char *)srISO.pszField55, srEMVTCRec.inSizeField55);
	
	unsigned char szTextBuff[10+1]; //Renu
	unsigned char szHexBuff[10+1]; //Renu
	memset(szEMVField55, NULL_CH, sizeof(szEMVField55));
	sprintf((char *)szTextBuff,"%04d", srEMVTCRec.inSizeField55);
	SVC_DSP_2_HEX((char *)szTextBuff, (char *)szHexBuff,2);
	memcpy(szEMVField55,szHexBuff, 2);
	memcpy(&szEMVField55[2], srEMVTCRec.szTCField55, srEMVTCRec.inSizeField55);
	LOG_PRINTFF((0x8L, "DE55=%s", szEMVField55));
	
}

void vdLoadEMVTCField22(TRANSACTION_OBJECT* pobTran){
	LOG_PRINTF(("vdLoadEMVTCField22"));
	strlcpy((char *) srISO.pszField22, (char *)srEMVTCRec.szPOSEntry, POS_EM_SIZE);
}

void vdLoadEMVTCField23(TRANSACTION_OBJECT* pobTran){
	//memset(szEMVField23, NULL_CH, sizeof(szEMVField23));
	LOG_PRINTF(("vdLoadEMVTCField23"));
	strlcpy((char *) srISO.pszField23, (char *)srEMVTCRec.szPANSeq, 4);
}

void vdLoadEMVTCField35(TRANSACTION_OBJECT* pobTran){
	LOG_PRINTF(("vdLoadEMVTCField35"));
 	memcpy((char *) srISO.pszField35, (char *)srEMVTCRec.stT2Data, TRACK2_SIZE);
}

void vdLoadEMVTCField03(TRANSACTION_OBJECT* pobTran){
	LOG_PRINTF(("vdLoadEMVTCField03"));
	memcpy((char *) srISO.pszField03, (char *)srEMVTCRec.szTCProcCode, PROC_CODE_SIZE);
	if(fLastRecord==VS_FALSE)
		srISO.pszField03[2]=((srISO.pszField03[2]) || 0x01);
	//srISO.pszField03[0]=0x94;
	//srISO.pszField03[1]=0x00;
	//if(fLastRecord==VS_TRUE)
	//	srISO.pszField03[2]=0x00;
	//else	
	//	srISO.pszField03[2]=0x01;
	
}

int inBuildEMVTCData(TRANSACTION_OBJECT *pobTran,unsigned char *pbtBuff, unsigned short *pusLen)
{
	int inOffset = 0;
	unsigned char btTmp[22];
	unsigned short usLen;
	char buff[256];
	
	if (usEMVGetTLVFromColxn(TAG_9F03_AMT_OTHER_NUM, btTmp, &usLen) != EMV_SUCCESS)
		{	// This DO seems to be needed even if it does not exist
			memset(btTmp, 0, 6);
			usEMVUpdateTLVInCollxn(TAG_9F03_AMT_OTHER_NUM, btTmp, 6);
			memset(buff, 0x00, sizeof(buff));
			hex_2_asc((BYTE *)buff, btTmp, 6);
			LOG_PRINTFF((0x08L, "TAG(0x%X): EMVUpdateTLV[TAG_9F03_AMT_OTHER_NUM = %s]", TAG_9F03_AMT_OTHER_NUM, buff));	
		} else {
			memset(buff, 0x00, sizeof(buff));
			if (usLen<128) hex_2_asc((BYTE *)buff, btTmp, usLen);
			LOG_PRINTFF((0x08L, "TAG(0x%X): EMVGetTLV[TAG_9F03_AMT_OTHER_NUM = %s]", TAG_9F03_AMT_OTHER_NUM, buff));	
		}

	inOffset += inAddDataToEMVPacket(TAG_8200_APPL_INTCHG_PROFILE, &pbtBuff[inOffset]);
	//inOffset += inAddDataToEMVPacket(TAG_84_DF_NAME, &pbtBuff[inOffset]);  //jrd 05182005
	inOffset += inAddDataToEMVPacket(TAG_9500_TVR, &pbtBuff[inOffset]);
	inOffset += inAddDataToEMVPacket(TAG_9A_TRAN_DATE, &pbtBuff[inOffset]);
	inOffset += inAddDataToEMVPacket(TAG_9C00_TRAN_TYPE, &pbtBuff[inOffset]);
	//inOffset += inAddDataToEMVPacket(TAG_5F2A_TRANS_CURCY_CODE, &pbtBuff[inOffset]); //jrd 05182005
	inOffset += inAddDataToEMVPacket(TAG_9F02_AMT_AUTH_NUM, &pbtBuff[inOffset]);
	inOffset += inAddDataToEMVPacket(TAG_9F03_AMT_OTHER_NUM, &pbtBuff[inOffset]);
	inOffset += inAddDataToEMVPacket(TAG_9F09_TERM_VER_NUM, &pbtBuff[inOffset]);
	inOffset += inAddDataToEMVPacket(TAG_9F10_ISSUER_APP_DATA, &pbtBuff[inOffset]);
	inOffset += inAddDataToEMVPacket(TAG_9F1A_TERM_COUNTY_CODE, &pbtBuff[inOffset]);
	inOffset += inAddDataToEMVPacket(TAG_9F1E_IFD_SER_NUM, &pbtBuff[inOffset]);
	inOffset += inAddDataToEMVPacket(TAG_9F26_APPL_CRYPTOGRAM, &pbtBuff[inOffset]);
	inOffset += inAddDataToEMVPacket(TAG_9F27_CRYPT_INFO_DATA, &pbtBuff[inOffset]);
	inOffset += inAddDataToEMVPacket(TAG_9F33_TERM_CAP, &pbtBuff[inOffset]);
	inOffset += inAddDataToEMVPacket(TAG_9F34_CVM_RESULTS, &pbtBuff[inOffset]);
	inOffset += inAddDataToEMVPacket(TAG_9F35_TERM_TYPE, &pbtBuff[inOffset]);
	inOffset += inAddDataToEMVPacket(TAG_9F36_ATC, &pbtBuff[inOffset]);
	inOffset += inAddDataToEMVPacket(TAG_9F37_UNPRED_NUM, &pbtBuff[inOffset]);
	inOffset += inAddDataToEMVPacket(TAG_9F41_TRANS_SEQ_COUNTER, &pbtBuff[inOffset]);
	inOffset += inAddDataToEMVPacket(TAG_9F53_TRAN_CURR_CODE, &pbtBuff[inOffset]);
	inOffset += inAddDataToEMVPacket(TAG_5F2A_TRANS_CURCY_CODE, &pbtBuff[inOffset]);
	inOffset += inAddDataToEMVPacket(TAG_5F34_APPL_PAN_SEQNUM, &pbtBuff[inOffset]); //edi
	inOffset += inAddDataToEMVPacket(TAG_84_DF_NAME, &pbtBuff[inOffset]);
	
	LOG_PRINTFF((0x8L, "BUILDTCDATA LENGTH=%d", inOffset));
	*pusLen = (unsigned short)inOffset;	
	return (VS_SUCCESS);
}

int inStoreTCEMVdata(TRANSACTION_OBJECT *pobTran, unsigned char *chTCData, unsigned short *pusLen)
{
	unsigned char bTagOutput[255];
	//unsigned short usLength;
	
	memset(bTagOutput, 0x00, sizeof(bTagOutput));
	inBuildEMVTCData(pobTran,(unsigned char *)bTagOutput, pusLen);
	
	memcpy(chTCData, bTagOutput, (*pusLen));
	
	return (VS_SUCCESS);
}

int inTCIncSTAN(void) {
    long lnSTAN;
  //  TRANSACTION_OBJECT* pobTran;

    lnSTAN = lnGetSTAN();

    if (++lnSTAN > lnMaxValue(inGetSTANSize()))
        lnSTAN = 1L;

    vdSetSTAN(lnSTAN);
    LOG_PRINTFF((0x8L, "TC_STAN=%ld", lnSTAN));
    return (inSaveMHTRec(inGetBatchIndex()));
}
